/**
 * SysUserServiceImpl.java
 */
package com.navidove.appspotlight.model.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import com.navidove.appspotlight.model.bo.SysUser;
import com.navidove.appspotlight.model.dao.SysUserDao;
import com.navidove.appspotlight.model.service.SysUserService;
import com.navidove.commons.exception.DataDuplicatedException;
import com.navidove.commons.utils.I18NUtil;
import com.navidove.commons.vo.Paging;

/**
 * SysUserServiceImpl
 *
 * @author $Author$
 * @version $Revision$
 * @date $Date$
 * @url $URL$
 */
@Service
public class SysUserServiceImpl implements SysUserService {
	
	@Autowired
	private SysUserDao sysUserDao;
	
	@Autowired(required=false)
	private PasswordEncoder passwordEncoder;
	
	/**
	 * @see com.navidove.appspotlight.model.service.SysUserService#getSysUsersByConditions(java.lang.String, java.lang.String, com.navidove.commons.vo.Paging)
	 */
	@SuppressWarnings("unchecked")
	public List<SysUser> getSysUsersByConditions(String username, String email,
			Paging paging) {

        DetachedCriteria criteria = DetachedCriteria.forClass(SysUser.class);

        if (StringUtils.isNotBlank(username)) {
            criteria.add(Restrictions.like("username", "%" + username + "%").ignoreCase());
        }

        if (StringUtils.isNotBlank(email)) {
            criteria.add(Restrictions.like("email", "%" + email + "%").ignoreCase());
        }
        return (List<SysUser>) sysUserDao.getListByCriteria(criteria, paging);
	}
	
	/**
	 * @see com.navidove.appspotlight.model.service.SysUserService#getSysUser(Long)
	 */
	public SysUser getSysUser(Long id) {
		return sysUserDao.get(id);
	}
	
	/**
	 * @see com.navidove.appspotlight.model.service.SysUserService#saveSysUser(com.navidove.appspotlight.model.bo.SysUser)
	 */
	public void saveSysUser(SysUser sysUser) {
	       // 檢查唯一
        sysUserDao.clear();
        DetachedCriteria criteria = DetachedCriteria.forClass(SysUser.class);
        criteria.add(Restrictions.eq("username", sysUser.getUsername()).ignoreCase());
        if (sysUser.getId()!=null) {
            criteria.add(Restrictions.ne("id", sysUser.getId()));
        }
        criteria.setProjection(Projections.rowCount());
        Number count = (Number) sysUserDao.getByCriteria(criteria);
        if (count.intValue() > 0) {
            throw new DataDuplicatedException(SysUser.class.getName());
        }

        Date now = new Date();
        if (sysUser.getId()==null) {
            sysUser.setPwd(encodePwd(sysUser.getUsername()));
            sysUser.setCrtAt(now);
        }
        sysUser.setUpdAt(now);
        sysUserDao.save(sysUser);
	}
	
	/**
	 * @see com.navidove.appspotlight.model.service.SysUserService#changePwd(java.lang.String, java.lang.String)
	 */
	public void changePwd(String pwd, String newPwd) {
        SysUser sysUser = getCurrentSysUser();
        
        if (!encodePwd(pwd).equals(sysUser.getPwd())) {
            String msg = I18NUtil.getMsg("dialog.message.entry.error.param",I18NUtil.getMsg("label.home.pwd.jsp.pwd.old"));
            throw new IllegalStateException(msg);
        }
        if (pwd.equals(newPwd)) {
            throw new IllegalStateException(I18NUtil.getMsg("dialog.home.pwd.jsp.pwd.neq.newPwd"));
        }
        sysUser.setPwd(encodePwd(newPwd));
        sysUserDao.save(sysUser);
	}
	
    /**
     * @see com.navidove.appspotlight.model.service.SysUserService#getCurrentSysUser()
     */
    public SysUser getCurrentSysUser() {
        SysUser sysUser = null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return null;
        }
        Object principal = authentication.getPrincipal();
        String username;
        if (principal instanceof UserDetails) {
            username = ((UserDetails) principal).getUsername();
        } else {
            username = principal.toString();
        }
        sysUser = sysUserDao.get(Restrictions.eq("username", username));
        return sysUser;
    }
    
    @SuppressWarnings("deprecation")
	protected String encodePwd(String pwd) {
    	if (passwordEncoder != null) {
    		return passwordEncoder.encodePassword(pwd, null);
    	}
        return pwd;
    }
}
